package cn.iocoder.yudao.module.asasc.common;

import cn.iocoder.yudao.module.asasc.dal.dataobject.campaign.AsaAppConfigDO;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.jetbrains.annotations.NotNull;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Properties;

/**
 * apple ads java demo
 */
@Slf4j
public class ASATokenUtils {
    // openssl pkcs8 -topk8 -inform pem -in private-key.pem -outform pem -nocrypt -out private-key-new.pem
    private static final String AUD = "https://appleid.apple.com";
    private static final String ALG = "ES256";
    private static final Properties properties = new Properties();

    static {
        try (InputStream input = ASATokenUtils.class.getClassLoader().getResourceAsStream("config.properties")) {
            if (input == null) {
                log.info("Sorry, unable to find config.properties");
            } else {
                properties.load(input);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        try {
            AsaAppConfigDO configDO = new AsaAppConfigDO();
            configDO.setOrgId(6451076370L);
            configDO.setPrivacyKey("-----BEGIN PRIVATE KEY-----\n" +
                            "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgkvPwuh9PsaVeOp+T\n" +
                            "CkmloWx3R51NuLQqOhPRHC7CVouhRANCAASc1AWNHgz5GVIcPRxYGMfKxQrwUKaT\n" +
                            "ciBpxj3UaKC6UU2XUb+aspR4Vb3vgEFQW0zCc0M1MSGEpQmc8+nQap1s\n" +
                            "-----END PRIVATE KEY-----")
                    .setClientId("SEARCHADS.c475fbdc-bbf0-4940-9296-2aa3926058f0")
                    .setTeamId("SEARCHADS.c475fbdc-bbf0-4940-9296-2aa3926058f0")
                    .setKeyId("d53901a1-8bca-4a9e-b985-adb94d9280b0");
            String clientSecret = createClientSecret(configDO);
            String asaToken = getAsaToken(configDO.getClientId(), clientSecret);
            System.out.println(asaToken);
        } catch (Exception e) {
            System.err.println("error");
        }
    }

    public static String getAsaToken(String clientId, String clientSecret) {
        try {
            String url = "https://appleid.apple.com/auth/oauth2/token";
            String urlParameters = "grant_type=client_credentials&scope=searchadsorg&client_id=" + clientId + "&client_secret=" + clientSecret;
            HttpURLConnection con = getUrlConnection(urlParameters, url);
            if (con.getResponseCode() == 200) {
                String result = IOUtils.toString(con.getInputStream(), StandardCharsets.UTF_8);
                JSONObject jsonObject = JSONObject.parseObject(result);
                return jsonObject.getString("access_token");
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return null;
    }

    private static @NotNull HttpURLConnection getUrlConnection(String urlParameters, String url) throws IOException {
        byte[] postData = urlParameters.getBytes(StandardCharsets.UTF_8);
        int postDataLength = postData.length;

        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
        con.setDoOutput(true);
        con.setRequestMethod("POST");
        con.setRequestProperty("charset", "utf-8");
        con.setRequestProperty("Content-Length", Integer.toString(postDataLength));
        con.setRequestProperty("Host", "appleid.apple.com");
        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        con.setUseCaches(false);
        try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
            wr.write(postData);
        }
        return con;
    }

    public static String createClientSecret(AsaAppConfigDO appConfigDO) {
        try {
            String privateKeyStr = appConfigDO.getPrivacyKey();
            String clientId = appConfigDO.getClientId();
            String teamId = appConfigDO.getTeamId();
            String keyId = appConfigDO.getKeyId();

            ECPrivateKey privateKey = (ECPrivateKey) PemUtils.readPrivateKeyFromString(privateKeyStr, "EC");
            ECPublicKey publicKey = null; // 如果需要公钥，可以从相应的文件或配置中读取

            Algorithm algorithm = Algorithm.ECDSA256(publicKey, privateKey);
            return JWT.create().withIssuer(teamId).withAudience(AUD).withHeader(new HashMap() {
                {
                    put("alg", ALG);
                    put("kid", keyId);
                }
            }).withSubject(clientId).withIssuedAt(new Date()).withExpiresAt(new Date(System.currentTimeMillis() + 86400 * 180 * 1000L)).sign(algorithm);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
